package com.ihrm.system.service.impl;

import com.ihrm.common.entity.ResultCode;
import com.ihrm.common.exception.CommonException;
import com.ihrm.common.service.BaseService;
import com.ihrm.common.utils.BeanMapUtils;
import com.ihrm.common.utils.IdWorker;
import com.ihrm.common.utils.PermissionConstants;
import com.ihrm.domain.system.Permission;
import com.ihrm.domain.system.PermissionApi;
import com.ihrm.domain.system.PermissionMenu;
import com.ihrm.domain.system.PermissionPoint;
import com.ihrm.system.dao.PermissionApiDao;
import com.ihrm.system.dao.PermissionDao;
import com.ihrm.system.dao.PermissionMenuDao;
import com.ihrm.system.dao.PermissionPointDao;
import com.ihrm.system.service.PermissionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * @author 小伟
 * @version V1.0
 * @Package com.ihrm.system.service.impl
 * @date 2020/12/14 13:45
 * @Copyright © 2020-2021 郑州恒星科技有限责任公司
 */
@Service
@Transactional
public class PermissionServiceImpl extends BaseService<PermissionServiceImpl> implements PermissionService {
    @Autowired
    PermissionDao permissionDao;
    @Autowired
    PermissionMenuDao permissionMenuDao;
    @Autowired
    PermissionPointDao permissionPointDao;
    @Autowired
    PermissionApiDao permissionApiDao;
    @Autowired
    IdWorker idWorker;

    /**
     * 添加权限
     * 根据type属性判断类型 1.菜单 2.按钮 3.api 封装全部信息到map中
     *
     * @param permissionMap 参数列表
     */
    @Override
    public void savePermission(Map<String, Object> permissionMap) throws Exception {
        //借助工具类生成id
        String id = idWorker.nextId() + "";
        //借助工具类把map中的属性提取到权限对象中
        Permission permission = BeanMapUtils.mapToBean(permissionMap, Permission.class);
        permission.setId(id);
        permissionDao.save(permission);
        Integer type = permission.getType();
        //根据前台传入的type值添加相应的权限资源
        switch (type) {
            case PermissionConstants.PY_MENU:
                PermissionMenu permissionMenu = BeanMapUtils.mapToBean(permissionMap, PermissionMenu.class);
                permissionMenu.setId(id);
                permissionMenuDao.save(permissionMenu);
                break;
            case PermissionConstants.PY_POINT:
                PermissionPoint permissionPoint = BeanMapUtils.mapToBean(permissionMap, PermissionPoint.class);
                permissionPoint.setId(id);
                permissionPointDao.save(permissionPoint);
                break;
            case PermissionConstants.PY_API:
                PermissionApi permissionApi = BeanMapUtils.mapToBean(permissionMap, PermissionApi.class);
                permissionApi.setId(id);
                permissionApiDao.save(permissionApi);
                break;
            default:
                throw new CommonException(ResultCode.FAIL);
        }
    }

    /**
     * 修改权限信息
     * 根据type属性判断类型 1.菜单 2.按钮 3.api 封装全部信息到map中
     *
     * @param permissionMap 参数列表
     */
    @Override
    public void updatePermission(Map<String, Object> permissionMap) throws Exception {
        String enVisible =(String) permissionMap.get("enVisible");
        if (!StringUtils.isEmpty(enVisible)) {
            permissionMap.put("enVisible", Integer.parseInt(enVisible));
        }
        //借助工具类把map中的属性提取到权限对象中
        Permission permission = BeanMapUtils.mapToBean(permissionMap, Permission.class);
        Integer type = permission.getType();
        //更新权限总表
        permissionDao.save(permission);
        //根据前台传入的type值添加相应的权限资源
        switch (type) {
            case PermissionConstants.PY_MENU:
                PermissionMenu permissionMenu = BeanMapUtils.mapToBean(permissionMap, PermissionMenu.class);
                permissionMenuDao.save(permissionMenu);
                break;
            case PermissionConstants.PY_POINT:
                PermissionPoint permissionPoint = BeanMapUtils.mapToBean(permissionMap, PermissionPoint.class);
                permissionPointDao.save(permissionPoint);
                break;
            case PermissionConstants.PY_API:
                PermissionApi permissionApi = BeanMapUtils.mapToBean(permissionMap, PermissionApi.class);
                permissionApiDao.save(permissionApi);
                break;
            default:
                throw new CommonException(ResultCode.FAIL);
        }
    }

    /**
     * 查询权限列表
     *
     * @param map 查询条件封装集合
     * @return 权限集合
     */
    @Override
    public List<Permission> findAll(Map<String, Object> map) {
        Specification spec = new Specification() {
            @Override
            public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder criteriaBuilder) {
                List<Predicate> predicateList = new ArrayList<>();
                //根据父id查询
                if (!StringUtils.isEmpty(map.get("pid"))) {
                    predicateList.add(criteriaBuilder.equal(root.get("pid").as(String.class), map.get("pid")));
                }
                //根据企业可见性查询
                if (!StringUtils.isEmpty(map.get("enVisible"))) {
                    predicateList.add(criteriaBuilder.equal(root.get("enVisible").as(String.class), map.get(
                            "enVisible")));
                }
                if (!StringUtils.isEmpty(map.get("type"))) {
                    String type = (String) map.get("type");
                    //构建in查询条件
                    CriteriaBuilder.In<Object> in = criteriaBuilder.in(root.get("type"));
                    if ("0".equals(type)) {
                        in.value(1).value(2);
                    } else {
                        in.value(Integer.parseInt(type));
                    }
                    predicateList.add(in);
                }
                return criteriaBuilder.and(predicateList.toArray(new Predicate[predicateList.size()]));
            }
        };
        return permissionDao.findAll(spec);
    }

    /**
     * 根据id查询权限信息
     *
     * @param id 权限id
     * @return 封装好的返回结果
     */
    @Override
    public Map<String, Object> findById(String id) throws CommonException {
        Permission permission = permissionDao.findById(id).get();
        Map<String, Object> map = new HashMap<>();
        Integer type = permission.getType();
        switch (type) {
            case PermissionConstants.PY_MENU:
                PermissionMenu permissionMenu = permissionMenuDao.findById(id).get();
                map = BeanMapUtils.beanToMap(permissionMenu);
                break;
            case PermissionConstants.PY_POINT:
                PermissionPoint permissionPoint = permissionPointDao.findById(id).get();
                map = BeanMapUtils.beanToMap(permissionPoint);
                break;
            case PermissionConstants.PY_API:
                PermissionApi permissionApi = permissionApiDao.findById(id).get();
                map = BeanMapUtils.beanToMap(permissionApi);
                break;
            default:
                throw new CommonException(ResultCode.FAIL);
        }
        map.put("name", permission.getName());
        map.put("type", permission.getType());
        map.put("code", permission.getCode());
        map.put("description", permission.getDescription());
        map.put("pid", permission.getPid());
        map.put("enVisible", permission.getEnVisible());

        return map;
    }

    /**
     * 根据id删除权限
     *
     * @param id 权限id
     */
    @Override
    public void deleteById(String id) throws CommonException {
        Permission permission = permissionDao.findById(id).get();
        Integer type = permission.getType();
        switch (type) {
            case PermissionConstants.PY_MENU:
                permissionMenuDao.deleteById(id);
                break;
            case PermissionConstants.PY_POINT:
                permissionPointDao.deleteById(id);
                break;
            case PermissionConstants.PY_API:
                permissionApiDao.deleteById(id);
                break;
            default:
                throw new CommonException(ResultCode.FAIL);
        }
        permissionDao.delete(permission);
    }
}
